package com.meessiom.train.crm.expense.service;

import com.meessiom.train.crm.common.exception.ResourceNotFoundException;
import com.meessiom.train.crm.expense.model.Expense;
import com.meessiom.train.crm.expense.repository.ExpenseRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMethod;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import lombok.extern.slf4j.Slf4j;

@Slf4j

@CrossOrigin(origins = "*", allowedHeaders = "*", methods = {
        RequestMethod.GET,
        RequestMethod.POST,
        RequestMethod.PUT,
        RequestMethod.DELETE,
        RequestMethod.OPTIONS
})
@Service
public class ExpenseService {
    @Autowired
    private ExpenseRepository expenseRepository;


    public void deleteExpense(long id) {
        Expense expense = expenseRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("Expense not exist with id" + id));

        expenseRepository.delete(expense);
    }

    public List<Expense> getAllExpenses(String expenseName, String expenseType, Date expenseDate,
                                        String supportName, String expenseState) {
        Specification<Expense> spec = Specification.where(null);

        if(expenseName != null && !expenseName.isEmpty()) {
            spec = spec.and((root, query, cb) ->
                    cb.like(root.get("expenseName"), "%" + expenseName + "%"));
        }

        if(expenseType != null && !expenseType.isEmpty()) {
            spec = spec.and((root, query, cb) ->
                    cb.equal(root.get("expenseType"), expenseType));
        }

        if(expenseDate != null) {
            spec = spec.and((root, query, cb) -> {
                return cb.between(root.get("expenseDate"),
                        expenseDate,
                        new Date(expenseDate.getTime() + 86400000)); // +1天
            });
        }

        if(supportName != null && !supportName.isEmpty()) {
            spec = spec.and((root, query, cb) ->
                    cb.like(root.get("supportName"), "%" + supportName + "%"));
        }

        if(expenseState != null && !expenseState.isEmpty()) {
            spec = spec.and((root, query, cb) ->
                    cb.equal(root.get("expenseState"), expenseState));
        }

        return expenseRepository.findAll(spec);
    }

    public Expense createExpense(Expense expense) {
        return expenseRepository.save(expense);
    }

    public Expense updateExpense(long id, Expense expenseDetails) {
        Expense expense = expenseRepository.findById(id)
                .orElseThrow(() -> new ResourceNotFoundException("Expense not found with id: " + id));

        expense.setExpenseName(expenseDetails.getExpenseName());
        expense.setRelatedCustomer(expenseDetails.getRelatedCustomer());
        expense.setExpensePrice(expenseDetails.getExpensePrice());
        expense.setExpenseType(expenseDetails.getExpenseType());
        expense.setExpenseDate(expenseDetails.getExpenseDate());
        expense.setExpenseState(expenseDetails.getExpenseState());
        expense.setSupportName(expenseDetails.getSupportName());

        return expenseRepository.save(expense);
    }


    public void importExpensesFromCsv(String csvContent) {
        String[] lines = csvContent.split("\r?\n");

        // 检查是否有表头
        boolean hasHeader = lines.length > 0 &&
                lines[0].contains("费用名称") || lines[0].contains("expenseName");

        int startLine = hasHeader ? 1 : 0;

        for (int i = startLine; i < lines.length; i++) {
            String line = lines[i].trim();
            if (line.isEmpty()) continue;

            try {
                String[] fields = line.split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)");
                if (fields.length < 7) {
                    log.warn("跳过不完整的行: {}", line);
                    continue;
                }

                Expense expense = new Expense();
                expense.setExpenseName(unwrapCsvField(fields[0]));
                expense.setExpenseType(unwrapCsvField(fields[1]));
                expense.setExpenseDate(parseDate(unwrapCsvField(fields[2])));
                expense.setSupportName(unwrapCsvField(fields[3]));
                expense.setExpenseState(unwrapCsvField(fields[4]));

                try {
                    expense.setExpensePrice(Double.parseDouble(unwrapCsvField(fields[5])));
                } catch (NumberFormatException e) {
                    log.error("无法解析金额: {}", fields[5]);
                    continue;
                }

                expense.setRelatedCustomer(unwrapCsvField(fields[6]));

                // 验证必填字段
                if (expense.getExpenseName() == null || expense.getExpenseName().isEmpty() ||
                        expense.getExpensePrice() <= 0) {
                    log.warn("跳过无效记录: {}", expense);
                    continue;
                }

                expenseRepository.save(expense);
            } catch (Exception e) {
                log.error("解析行 {} 错误: {}", i, line, e);
            }
        }
    }

    private String unwrapCsvField(String field) {
        if (field.startsWith("\"") && field.endsWith("\"")) {
            return field.substring(1, field.length() - 1).replace("\"\"", "\"");
        }
        return field;
    }

    public String exportExpensesToCsv(String expenseName, String expenseType, Date expenseDate,
                                      String supportName, String expenseState) {
        List<Expense> expenses = getAllExpenses(
                expenseName, expenseType, expenseDate, supportName, expenseState);

        StringBuilder csv = new StringBuilder();
        // 表头
        csv.append("费用名称,费用类型,发生时间,负责人员,报销状态,费用金额,关联客户\r\n");

        // 数据行
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        for (Expense expense : expenses) {
            csv.append(escapeCsv(expense.getExpenseName())).append(",")
                    .append(escapeCsv(expense.getExpenseType())).append(",")
                    .append(expense.getExpenseDate() != null ? dateFormat.format(expense.getExpenseDate()) : "").append(",")
                    .append(escapeCsv(expense.getSupportName())).append(",")
                    .append(escapeCsv(expense.getExpenseState())).append(",")
                    .append(expense.getExpensePrice()).append(",")
                    .append(escapeCsv(expense.getRelatedCustomer()))
                    .append("\r\n");
        }

        return csv.toString();
    }

    private String escapeCsv(String value) {
        if (value == null) return "";
        if (value.contains(",") || value.contains("\"")) {
            return "\"" + value.replace("\"", "\"\"") + "\"";
        }
        return value;
    }

    private Date parseDate(String dateStr) {
        try {
            // 尝试多种日期格式
            String[] patterns = {"yyyy-MM-dd", "yyyy/MM/dd", "yyyy.MM.dd"};
            for (String pattern : patterns) {
                try {
                    SimpleDateFormat sdf = new SimpleDateFormat(pattern);
                    return sdf.parse(dateStr);
                } catch (Exception e) {
                    continue;
                }
            }
            return new Date(); // 如果所有格式都失败，返回当前日期
        } catch (Exception e) {
            return new Date();
        }
    }



}
